package com.bac.rentmap.ad.flat.crawler.blingby;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.bac.rentmap.ad.flat.crawler.FlatCrawledAd;
import com.bac.rentmap.ad.flat.crawler.localaddress.LocalAddressParser;

/**
 * Load ads. Parse ads satisfying the following conditions: city: minsk, currency : USD, not room, not agent.
 * 
 * @author Andrew
 */
public class BlingBySaxHandler extends DefaultHandler {
    private List<FlatCrawledAd> res;
    private FlatCrawledAd flatCrawledAd;
    private String currentValue;
    private SimpleDateFormat dateFormat;
    
    private LocalAddressParser localAddressParser;
    
    private String value;
    
    public BlingBySaxHandler(LocalAddressParser localAddressParser) {
        super();
        this.localAddressParser = localAddressParser;
        res = new ArrayList<FlatCrawledAd>();
        dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        if("offer".equals(qName)){
            flatCrawledAd = new FlatCrawledAd();
            flatCrawledAd.setReadyForTransformation(Boolean.TRUE);
            flatCrawledAd.setSourceUrl(BlingByAdCrawler.SOURCE_URL);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        super.endElement(uri, localName, qName);
        if(flatCrawledAd == null){
            return;
        }
        if("locality-name".equals(qName)){
            if("Минск".equals(currentValue)){
                flatCrawledAd.setCity("minsk");
            }
            else{
                flatCrawledAd = null;
            }
        }
        else if("category".equals(qName)){
            if(!("квартира".equals(currentValue) || "владелец".equals(currentValue))){
                flatCrawledAd = null;
            }
        }
        else if("currency".equals(qName)){
            if(!"USD".equals(currentValue)){
                flatCrawledAd = null;
            }
        }
        else if("value".equals(qName)){
            value = currentValue;
        }
        else if("price".equals(qName)){
            flatCrawledAd.setPrice(Integer.valueOf(value));
        }
        else if("address".equals(qName)){
            flatCrawledAd.setLocalAddress(localAddressParser.parse(currentValue));
        }
        else if("description".equals(qName)){
            flatCrawledAd.setDescription(currentValue);
        }
        else if("rooms".equals(qName)){
            flatCrawledAd.setRoom(currentValue);
        }
        else if("url".equals(qName)){
            flatCrawledAd.setExternalUrl(currentValue);
        }
        else if("phone".equals(qName)){
            flatCrawledAd.setPhone(currentValue);
        }
        else if("last-update-date".equals(qName)){
            try {
                flatCrawledAd.setPublishingDate(dateFormat.parse(currentValue));
            } catch (ParseException e) {
                throw new RuntimeException("Failed to parse last-update-date", e);
            }
        }
        else if("image".equals(qName)){
            List<String> externalImages = flatCrawledAd.getExternalImages();
            if(externalImages == null){
                flatCrawledAd.setExternalImages(externalImages = new ArrayList<String>());
            }
            externalImages.add(currentValue);
        }
        else if("offer".equals(qName)){
            res.add(flatCrawledAd);
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        super.characters(ch, start, length);
        currentValue = new String(ch, start, length);
    }

    public List<FlatCrawledAd> getRes() {
        return res;
    }
}
